package com.itcast.service.base;

import java.util.LinkedHashMap;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.itcast.bean.QueryResult;

@Transactional
public class DaoSupport implements DAO{
	@PersistenceContext protected EntityManager em;
	@Override
	public void save(Object entity) {
		em.persist(entity);
	}

	@Override
	public void update(Object entity) {
		em.merge(entity);
	}

	@Override
	public <T> void delete(Class<T> entityClass, Object entityid) {
		delete(entityClass,new Object[]{entityid});
	}

	@Override
	public <T> void delete(Class<T> entityClass, Object[] entityids) {
		for(Object id:entityids){
			em.remove(em.getReference(entityClass, id));
		}
	}

	@Override
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public <T> T find(Class<T> entityClass, Object entityId) {
		return em.find(entityClass, entityId);
	}
	@SuppressWarnings("unchecked")
	@Override
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,int firstindex, int Maxresult,String wherejpql,Object[] queryParams,
			LinkedHashMap<String, String> orderby) {
		QueryResult<T> qr=new QueryResult<T>();
		String entityname=getEntityName(entityClass);
		Query query=em.createQuery("select o from "+entityname+" o "+(wherejpql == null ? "":" where "+wherejpql)+buildOrderby(orderby));
		setQueryParams(query, queryParams);
		if(firstindex != -1 && Maxresult != -1){
			query.setFirstResult(firstindex).setMaxResults(Maxresult);
		}
		qr.setResultlist(query.getResultList());
		query=em.createQuery("select count(o) from "+entityname+" o"+(wherejpql == null ? "":" where "+wherejpql));
		setQueryParams(query, queryParams);
		qr.setTotalrecord((Long)query.getSingleResult());
		return qr;
	}
	protected void setQueryParams(Query query,Object[] queryParams){
		if(queryParams != null && queryParams.length>0){
			for(int i=0;i<queryParams.length;i++){
				query.setParameter(i+1, queryParams[i]);
			}
		}
	}
	/**
	 * 组装ordryBy语句
	 * @param orderby
	 * @return
	 */
	protected String buildOrderby(LinkedHashMap<String,String> orderby) {
		StringBuffer orderbyql=new StringBuffer("");
		if(orderby !=null && orderby.size()>0){
			orderbyql.append(" order by ");
			//orderby o.key desc,o.key2 asc
			for(String key:orderby.keySet()){
				orderbyql.append(" o.").append(key).append(" ").append(orderby.get(key)).append(",");
			}
			orderbyql.deleteCharAt(orderbyql.length()-1);
		}
		return orderbyql.toString();	
	}
	protected <T> String getEntityName(Class<T> entityClass){
		String entityname=entityClass.getSimpleName();
		Entity entity =entityClass.getAnnotation(Entity.class);
		if(entity.name() !=null && !"".equals(entity.name())){
			entityname=entity.name();
		}
		
		return entityname;
	}

	@Override
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	/**
	 * 按条件查询，但是不排序
	 */
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,
			int firstindext, int maxresult, String wherejpql,
			Object[] queryParams) {
		
		return getScrollData(entityClass, firstindext, maxresult, wherejpql, queryParams, null);
	}

	@Override
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	/**
	 * 查询分页排序
	 */
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,
			int firstindext, int maxresult,
			LinkedHashMap<String, String> orderby) {
		return getScrollData(entityClass, firstindext, maxresult, null,null,orderby);
	}

	@Override
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	/**
	 * 分页，但不排序
	 */
	public <T> QueryResult<T> getScrollData(Class<T> entityClass,
			int firstindext, int maxresult) {
		return getScrollData(entityClass, firstindext, maxresult, null, null, null);
	}

	@Override
	@Transactional(readOnly=true,propagation=Propagation.NOT_SUPPORTED)
	/**
	 * 查询全部
	 */
	public <T> QueryResult<T> getScrollData(Class<T> entityClass) {
		return getScrollData(entityClass, -1, -1, null, null, null);
	}
}
